Implement GtkInspectorLayoutOverlay
authorTimm Bäder <mail@baedert.org>
Sun, 8 Jul 2018 09:26:12 +0000 (11:26 +0200)
committerTimm Bäder <mail@baedert.org>
Sun, 8 Jul 2018 09:26:12 +0000 (11:26 +0200)
To properly replace the old "show layout borders" option.

gtk/gtkwidget.c
gtk/inspector/layoutoverlay.c [new file with mode: 0644]
gtk/inspector/layoutoverlay.h [new file with mode: 0644]
gtk/inspector/meson.build
gtk/inspector/visual.c

index e76c07279a62b03733f5063ba4e42ed6af8d0029..b4ae9442e405c244fa8ac6260e26801b4cab7fe7 100644 (file)
@@ -13011,96 +13011,6 @@ gtk_widget_maybe_add_debug_render_nodes (GtkWidget             *widget,
 
   /* We should be offset to priv->allocation at this point */
 
-  if (GTK_DISPLAY_DEBUG_CHECK (display, LAYOUT))
-    {
-      graphene_rect_t bounds;
-      GdkRGBA widget_margin_color = {0.7, 0,   0, 0.6};
-      GdkRGBA margin_color        = {0.7, 0.7, 0, 0.6};
-      GdkRGBA padding_color       = {0.7, 0, 0.7, 0.6};
-
-      style = gtk_css_node_get_style (priv->cssnode);
-      get_box_margin (style, &margin);
-      get_box_border (style, &border);
-      get_box_padding (style, &padding);
-
-      gtk_snapshot_push_debug (snapshot, "Widget layout debugging");
-
-      /* Widget margins */
-      graphene_rect_init (&bounds,
-                          0, -priv->margin.top,
-                          priv->allocation.width, priv->margin.top);
-      gtk_snapshot_append_color (snapshot, &widget_margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          0, priv->allocation.height,
-                          priv->allocation.width, priv->margin.bottom);
-      gtk_snapshot_append_color (snapshot, &widget_margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          -priv->margin.left, 0,
-                          priv->margin.left, priv->allocation.height);
-      gtk_snapshot_append_color (snapshot, &widget_margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          priv->allocation.width, 0,
-                          priv->margin.right, priv->allocation.height);
-      gtk_snapshot_append_color (snapshot, &widget_margin_color, &bounds);
-
-
-      /* CSS Margins */
-      graphene_rect_init (&bounds,
-                          0, 0,
-                          priv->allocation.width, margin.top);
-      gtk_snapshot_append_color (snapshot, &margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          0, priv->allocation.height - margin.bottom,
-                          priv->allocation.width, margin.bottom);
-      gtk_snapshot_append_color (snapshot, &margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          0, margin.top,
-                          margin.left, priv->allocation.height - margin.top - margin.bottom);
-      gtk_snapshot_append_color (snapshot, &margin_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          priv->allocation.width - margin.right, margin.top,
-                          margin.right, priv->allocation.height - margin.top - margin.bottom);
-      gtk_snapshot_append_color (snapshot, &margin_color, &bounds);
-
-
-      /* Padding */
-      graphene_rect_init (&bounds,
-                          margin.left + border.left,
-                          margin.top + border.top,
-                          priv->allocation.width - margin.left - margin.right - border.left - border.right,
-                          padding.top);
-      gtk_snapshot_append_color (snapshot, &padding_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          margin.left + border.left,
-                          priv->allocation.height - margin.bottom - border.bottom - padding.bottom,
-                          priv->allocation.width - margin.left - margin.right - border.left - border.right,
-                          padding.bottom);
-      gtk_snapshot_append_color (snapshot, &padding_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          margin.left + border.left,
-                          margin.top + border.top + padding.top,
-                          padding.left,
-                          priv->allocation.height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom);
-      gtk_snapshot_append_color (snapshot, &padding_color, &bounds);
-
-      graphene_rect_init (&bounds,
-                          priv->allocation.width - margin.right - border.right - padding.right,
-                          margin.top + border.top + padding.top,
-                          padding.right,
-                          priv->allocation.height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom);
-      gtk_snapshot_append_color (snapshot, &padding_color, &bounds);
-
-      gtk_snapshot_pop (snapshot);
-    }
-
   if (GTK_DISPLAY_DEBUG_CHECK (display, BASELINES))
     {
       int baseline = gtk_widget_get_allocated_baseline (widget);
diff --git a/gtk/inspector/layoutoverlay.c b/gtk/inspector/layoutoverlay.c
new file mode 100644 (file)
index 0000000..b2f8601
--- /dev/null
@@ -0,0 +1,222 @@
+
+#include "config.h"
+#include "layoutoverlay.h"
+#include "gtkwidgetprivate.h"
+#include "gtkcssstyleprivate.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+
+static const GdkRGBA WIDGET_MARGIN_COLOR = {0.7, 0,   0, 0.6};
+static const GdkRGBA MARGIN_COLOR        = {0.7, 0.7, 0, 0.6};
+static const GdkRGBA PADDING_COLOR       = {0.7, 0, 0.7, 0.6};
+
+struct _GtkLayoutOverlay
+{
+  GtkInspectorOverlay parent_instance;
+};
+
+struct _GtkLayoutOverlayClass
+{
+  GtkInspectorOverlayClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkLayoutOverlay, gtk_layout_overlay, GTK_TYPE_INSPECTOR_OVERLAY)
+
+
+static gint
+get_number (GtkCssStyle *style,
+            guint        property)
+{
+  double d = _gtk_css_number_value_get (gtk_css_style_get_value (style, property), 100);
+
+  if (d < 1)
+    return ceil (d);
+  else
+    return floor (d);
+}
+
+static void
+get_box_margin (GtkCssStyle *style,
+                GtkBorder   *margin)
+{
+  margin->top = get_number (style, GTK_CSS_PROPERTY_MARGIN_TOP);
+  margin->left = get_number (style, GTK_CSS_PROPERTY_MARGIN_LEFT);
+  margin->bottom = get_number (style, GTK_CSS_PROPERTY_MARGIN_BOTTOM);
+  margin->right = get_number (style, GTK_CSS_PROPERTY_MARGIN_RIGHT);
+}
+
+static void
+get_box_border (GtkCssStyle *style,
+                GtkBorder   *border)
+{
+  border->top = get_number (style, GTK_CSS_PROPERTY_BORDER_TOP_WIDTH);
+  border->left = get_number (style, GTK_CSS_PROPERTY_BORDER_LEFT_WIDTH);
+  border->bottom = get_number (style, GTK_CSS_PROPERTY_BORDER_BOTTOM_WIDTH);
+  border->right = get_number (style, GTK_CSS_PROPERTY_BORDER_RIGHT_WIDTH);
+}
+
+static void
+get_box_padding (GtkCssStyle *style,
+                 GtkBorder   *border)
+{
+  border->top = get_number (style, GTK_CSS_PROPERTY_PADDING_TOP);
+  border->left = get_number (style, GTK_CSS_PROPERTY_PADDING_LEFT);
+  border->bottom = get_number (style, GTK_CSS_PROPERTY_PADDING_BOTTOM);
+  border->right = get_number (style, GTK_CSS_PROPERTY_PADDING_RIGHT);
+}
+
+static void
+recurse_child_widgets (GtkWidget   *widget,
+                       GtkSnapshot *snapshot)
+{
+  GtkBorder margin, border, padding;
+  GtkBorder widget_margin;
+  GtkAllocation allocation;
+  graphene_rect_t bounds;
+  GtkCssStyle *style;
+  GtkWidget *child;
+
+  if (!gtk_widget_get_mapped (widget))
+    return;
+
+  style = gtk_css_node_get_style (gtk_widget_get_css_node (widget));
+  get_box_margin (style, &margin);
+  get_box_border (style, &border);
+  get_box_padding (style, &padding);
+
+  /* TODO: Eh, left = start? RTL? */
+  widget_margin.left = gtk_widget_get_margin_start (widget);
+  widget_margin.top = gtk_widget_get_margin_top (widget);
+  widget_margin.right = gtk_widget_get_margin_end (widget);
+  widget_margin.bottom = gtk_widget_get_margin_bottom (widget);
+
+  gtk_widget_get_allocation (widget, &allocation);
+
+
+  /* Offset for all of the drawing done here. We assume cooridinates relative to
+   * the widget allocation, not the content allocation. */
+  gtk_snapshot_offset (snapshot, allocation.x, allocation.y);
+
+  /* Now do all the stuff */
+  gtk_snapshot_push_debug (snapshot, "Widget layout debugging");
+
+  /* Widget margins */
+  graphene_rect_init (&bounds,
+                      0, -widget_margin.top,
+                      allocation.width, widget_margin.top);
+  gtk_snapshot_append_color (snapshot, &WIDGET_MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      0, allocation.height,
+                      allocation.width, widget_margin.bottom);
+  gtk_snapshot_append_color (snapshot, &WIDGET_MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      -widget_margin.left, 0,
+                      widget_margin.left, allocation.height);
+  gtk_snapshot_append_color (snapshot, &WIDGET_MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      allocation.width, 0,
+                      widget_margin.right, allocation.height);
+  gtk_snapshot_append_color (snapshot, &WIDGET_MARGIN_COLOR, &bounds);
+
+
+  /* CSS Margins */
+  graphene_rect_init (&bounds,
+                      0, 0,
+                      allocation.width, margin.top);
+  gtk_snapshot_append_color (snapshot, &MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      0, allocation.height - margin.bottom,
+                      allocation.width, margin.bottom);
+  gtk_snapshot_append_color (snapshot, &MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      0, margin.top,
+                      margin.left, allocation.height - margin.top - margin.bottom);
+  gtk_snapshot_append_color (snapshot, &MARGIN_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      allocation.width - margin.right, margin.top,
+                      margin.right, allocation.height - margin.top - margin.bottom);
+  gtk_snapshot_append_color (snapshot, &MARGIN_COLOR, &bounds);
+
+
+  /* Padding */
+  graphene_rect_init (&bounds,
+                      margin.left + border.left,
+                      margin.top + border.top,
+                      allocation.width - margin.left - margin.right - border.left - border.right,
+                      padding.top);
+  gtk_snapshot_append_color (snapshot, &PADDING_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      margin.left + border.left,
+                      allocation.height - margin.bottom - border.bottom - padding.bottom,
+                      allocation.width - margin.left - margin.right - border.left - border.right,
+                      padding.bottom);
+  gtk_snapshot_append_color (snapshot, &PADDING_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      margin.left + border.left,
+                      margin.top + border.top + padding.top,
+                      padding.left,
+                      allocation.height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom);
+  gtk_snapshot_append_color (snapshot, &PADDING_COLOR, &bounds);
+
+  graphene_rect_init (&bounds,
+                      allocation.width - margin.right - border.right - padding.right,
+                      margin.top + border.top + padding.top,
+                      padding.right,
+                      allocation.height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom);
+  gtk_snapshot_append_color (snapshot, &PADDING_COLOR, &bounds);
+
+  gtk_snapshot_pop (snapshot);
+
+
+  /* Recurse into child widgets */
+  for (child = gtk_widget_get_first_child (widget);
+       child != NULL;
+       child = gtk_widget_get_next_sibling (child))
+    {
+      const int offset_x = margin.left + border.left + padding.left;
+      const int offset_y = margin.top + border.top + padding.top;
+
+      gtk_snapshot_offset (snapshot, offset_x, offset_y);
+      recurse_child_widgets (child, snapshot);
+      gtk_snapshot_offset (snapshot, - offset_x, - offset_y);
+    }
+
+  gtk_snapshot_offset (snapshot, - allocation.x, - allocation.y);
+}
+
+static void
+gtk_layout_overlay_snapshot (GtkInspectorOverlay *overlay,
+                             GtkSnapshot         *snapshot,
+                             GskRenderNode       *node,
+                             GtkWidget           *widget)
+{
+  recurse_child_widgets (widget, snapshot);
+}
+
+static void
+gtk_layout_overlay_init (GtkLayoutOverlay *self)
+{
+
+}
+
+static void
+gtk_layout_overlay_class_init (GtkLayoutOverlayClass *klass)
+{
+  GtkInspectorOverlayClass *overlay_class = (GtkInspectorOverlayClass *)klass;
+
+  overlay_class->snapshot = gtk_layout_overlay_snapshot;
+}
+
+GtkInspectorOverlay *
+gtk_layout_overlay_new (void)
+{
+  return g_object_new (GTK_TYPE_LAYOUT_OVERLAY, NULL);
+}
diff --git a/gtk/inspector/layoutoverlay.h b/gtk/inspector/layoutoverlay.h
new file mode 100644 (file)
index 0000000..ef44dc1
--- /dev/null
@@ -0,0 +1,19 @@
+
+
+#ifndef __GTK_LAYOUT_OVERLAY_H__
+#define __GTK_LAYOUT_OVERLAY_H__
+
+#include "inspectoroverlay.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_LAYOUT_OVERLAY             (gtk_layout_overlay_get_type ())
+G_DECLARE_FINAL_TYPE (GtkLayoutOverlay, gtk_layout_overlay, GTK, LAYOUT_OVERLAY, GtkInspectorOverlay)
+
+GtkInspectorOverlay *   gtk_layout_overlay_new                 (void);
+
+G_END_DECLS
+
+
+
+#endif
index 3f241585f5a08a838dfebaa8b6caecc6739ec0ab..9184e14e5fd097a17f985d9ab27e269e15beb81d 100644 (file)
@@ -16,6 +16,7 @@ inspector_sources = files(
   'init.c',
   'inspect-button.c',
   'inspectoroverlay.c',
+  'layoutoverlay.c',
   'logs.c',
   'magnifier.c',
   'menu.c',
index 23bd75309723320cb409e6db65ec639295da6cb0..87ea1cf9979ff7455d4b5f206eece339f1a20840 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "fpsoverlay.h"
 #include "updatesoverlay.h"
+#include "layoutoverlay.h"
 #include "window.h"
 
 #include "gtkadjustment.h"
@@ -81,6 +82,7 @@ struct _GtkInspectorVisualPrivate
 
   GtkInspectorOverlay *fps_overlay;
   GtkInspectorOverlay *updates_overlay;
+  GtkInspectorOverlay *layout_overlay;
 };
 
 G_DEFINE_TYPE_WITH_PRIVATE (GtkInspectorVisual, gtk_inspector_visual, GTK_TYPE_SCROLLED_WINDOW)
@@ -313,18 +315,37 @@ baselines_activate (GtkSwitch *sw)
 }
 
 static void
-layout_activate (GtkSwitch *sw)
+layout_activate (GtkSwitch          *sw,
+                 GParamSpec         *pspec,
+                 GtkInspectorVisual *vis)
 {
-  guint flags;
+  GtkInspectorVisualPrivate *priv = vis->priv;
+  GtkInspectorWindow *iw;
+  gboolean draw_layout;
 
-  flags = gtk_get_debug_flags ();
+  draw_layout = gtk_switch_get_active (sw);
+  iw = GTK_INSPECTOR_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (vis)));
+  if (iw == NULL)
+    return;
 
-  if (gtk_switch_get_active (sw))
-    flags |= GTK_DEBUG_LAYOUT;
+  if (draw_layout)
+    {
+      if (priv->updates_overlay == NULL)
+        {
+          priv->updates_overlay = gtk_layout_overlay_new ();
+          gtk_inspector_window_add_overlay (iw, priv->updates_overlay);
+          g_object_unref (priv->updates_overlay);
+        }
+    }
   else
-    flags &= ~GTK_DEBUG_LAYOUT;
+    {
+      if (priv->updates_overlay != NULL)
+        {
+          gtk_inspector_window_remove_overlay (iw, priv->updates_overlay);
+          priv->updates_overlay = NULL;
+        }
+    }
 
-  gtk_set_debug_flags (flags);
   redraw_everything ();
 }